package cn.xie.domain.strategy.service.rule.impl;

import cn.xie.domain.strategy.model.entity.RuleActionEntity;
import cn.xie.domain.strategy.model.entity.RuleFillerEntity;
import cn.xie.domain.strategy.model.entity.StrategyEntity;
import cn.xie.domain.strategy.model.entity.StrategyRuleEntity;
import cn.xie.domain.strategy.model.vo.RuleFillerCheckVO;
import cn.xie.domain.strategy.repository.IStrategyRepository;
import cn.xie.domain.strategy.service.annotation.LogicStrategy;
import cn.xie.domain.strategy.service.rule.IRuleFiller;
import cn.xie.domain.strategy.service.rule.factory.DefaultRuleFactory;
import cn.xie.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: xiaoxie
 * create: 2025-08-08 22:48
 * @BelongsProject: bit-market
 * @BelongsPackage: cn.xie.domain.strategy.service.rule.impl
 * description: 权重规则过滤
 */
@Slf4j
@Service
@LogicStrategy(ruleModel = DefaultRuleFactory.RuleModel.RULE_WEIGHT)
public class RuleWeightFillerImpl implements IRuleFiller<RuleActionEntity.RaffleRuleBeforeEntity> {

    @Resource
    private IStrategyRepository strategyRepository;
    // 暂时使用mock的数
    public Long userScore = 4500L;

    @Override
    public RuleActionEntity<RuleActionEntity.RaffleRuleBeforeEntity> filler(RuleFillerEntity ruleFillerEntity) {
        log.info("规则过滤-权重范围 userId:{} strategyId:{} ruleModel:{}", ruleFillerEntity.getUserId(), ruleFillerEntity.getStrategyId(), ruleFillerEntity.getRuleModel());
        StrategyEntity strategyEntity = strategyRepository.queryStrategyByStrategyId(ruleFillerEntity.getStrategyId());
        String[] ruleModels = strategyEntity.getRuleModels();
        if (ruleModels == null || ruleModels.length == 0 ||
                !Arrays.asList(ruleModels).contains(Constants.StrategyRule.RULE_WEIGHT)) {
            // 没有黑名单规则，直接放行
            return allow();
        }
        // 如果有的话就获取到 ruleValue
        String ruleValue = strategyRepository.queryStrategyRuleValue(ruleFillerEntity.getStrategyId()
                , ruleFillerEntity.getAwardId(), ruleFillerEntity.getRuleModel());
        Map<Long, String> userScoreRuleValueMap = getAnalyticalValue(ruleValue);
        if (userScoreRuleValueMap.isEmpty()) {
            return allow();
        }
        // 先获取到userScoreList
        List<Long> userScoreList = new ArrayList<>(userScoreRuleValueMap.keySet());
        //降序
        userScoreList.sort(Collections.reverseOrder());
        Long key = userScoreList.stream()
                .filter(score -> userScore >= score)
                .findFirst()
                .orElse(null);
        if(null != key){
            return takeOver(ruleFillerEntity.getStrategyId(),userScoreRuleValueMap.get(key));
        }
        return allow();
    }
    // 4000:102,103,104,105 5000:102,103,104,105,106,107 6000:102,103,104,105,106,107,108,109
    private Map<Long,String> getAnalyticalValue(String ruleValue) {
        // 保持插入顺序
        Map<Long, String> map = new LinkedHashMap<>();
        if (ruleValue == null || ruleValue.trim().isEmpty()) {
            return map;
        }

        for (String group : ruleValue.trim().split(Constants.SPACE)) {
            String[] kv = group.split(Constants.COLON, 2);
            if (kv.length != 2) {
                log.warn("权重规则格式错误：{}", group);
                continue;
            }
            try {
                Long score = Long.valueOf(kv[0].trim());
                // 保留原始段，便于后续使用
                map.put(score, group);
            } catch (NumberFormatException e) {
                log.warn("权重规则分数非法：{}", kv[0]);
            }
        }
        return map;
    }

    // 放行
    private RuleActionEntity<RuleActionEntity.RaffleRuleBeforeEntity> allow() {
        return RuleActionEntity.<RuleActionEntity.RaffleRuleBeforeEntity>builder()
                .code(RuleFillerCheckVO.ALLOW.getCode())
                .info(RuleFillerCheckVO.ALLOW.getInfo())
                .build();
    }
    // 接管
    private RuleActionEntity<RuleActionEntity.RaffleRuleBeforeEntity> takeOver(Long strategyId,String ruleWeightValue) {
        return RuleActionEntity.<RuleActionEntity.RaffleRuleBeforeEntity>builder()
                .code(RuleFillerCheckVO.TAKE_OVER.getCode())
                .info(RuleFillerCheckVO.TAKE_OVER.getInfo())
                .ruleModel(DefaultRuleFactory.RuleModel.RULE_WEIGHT.getCode())
                .data(RuleActionEntity.RaffleRuleBeforeEntity.builder()
                        .strategyId(strategyId)
                        .ruleWeightValue(ruleWeightValue)
                        .build())
                .build();
    }
}
